import logging
import os.path

from html_parse.HtmlXPathParser import HTMLTREE, HtmlXPath
from utils import CommonUtils
import json

JSON_FILE = r"G:\ututes\Code\tools\ututes_html_process\resources\navigation\index.json"


def parse_programs(html_file_path):
    program_html_tree = HTMLTREE(html_file_path, HtmlXPath.PROGRAM_XPATH)
    program_parse_info = program_html_tree.parse_program_html()
    # todo 考虑增加结果校验
    return program_parse_info


def parse_degree(html_file_path):
    degree_html_tree = HTMLTREE(html_file_path, HtmlXPath.DEGREE_XPATH)
    degree_parse_info = degree_html_tree.parse_degree_html()
    # todo 考虑增加结果校验
    return degree_parse_info


def get_core_courses(courses, program_requirement):
    """
    获取核心课程
    :param courses: 所有课程
    :param program_requirement: 专业要求描述
    :return:
    """
    core_courses = []
    for course in courses:
        # 处理专业名，去除专业名中的括号和内容
        course_processed = CommonUtils.TextUtils.remove_brackets_and_contents(course)
        if CommonUtils.TextUtils.contains_word(program_requirement, course_processed):
            core_courses.append(course)
    return core_courses


def process_programs_and_degree(program_file_path, degree_file_path):
    """
    解析专业和学位课程信息
    :param program_file_path:
    :param degree_file_path:
    :return:
    """
    programs_info = parse_programs(program_file_path)
    courses_info = parse_degree(degree_file_path)

    # 获取专业要求描述
    program_requirements = programs_info.get("program_requirements")
    program_requirement_text = CommonUtils.TextUtils.concatenate_strings_with_separator(program_requirements)
    # 获取专业名称
    program_title = programs_info.get("program_title")
    # 循环得到的课程信息，找到专业所需课程信息
    for course in courses_info:
        course_program_title = course.get("title")
        if CommonUtils.TextUtils.contains_word(course_program_title, program_title):
            core_courses = get_core_courses(course.get("courses"), program_requirement_text)
            print(core_courses)


def get_file_name_by_md5(md5):
    with open(JSON_FILE, 'r') as file:
        mapping_list = json.load(file)
    for mapping in mapping_list:
        url_mapping = mapping.get("url")
        md5_mapping = mapping.get("md5")
        if md5 == md5_mapping:
            return url_mapping
    return None


def process(navigation_file_path, source_path):
    """
    html解析
    1. 解析导航页面，获取[专业名称]和[专业信息的url(program)]
    2. 计算获取[专业信息url(program)]的md5值，去映射文件中查找是否存在该专业信息页面
    3. 如果存在，则解析专业信息，同时获取专业对应的[学位课程url(degree)]
    4. 计算获取[学位课程url(degree)]的md5值，去映射文件中查找是否存在该学位课程信息页面
    5. 如果存在，则解析学位课程信息，同时获取核心课程信息
    :param navigation_file_path: 导航文件路径
    :param source_path: html资源文件路径
    :return:
    """
    # 1. 解析导航页面，获取[专业名称]和[专业信息的url(program)]
    navigation_tree = HTMLTREE(navigation_file_path, HtmlXPath.PROGRAM_NAVIGATION_XPATH)
    programs_and_url_list = navigation_tree.parse_program_navigation_html_v2()
    # 循环处理每个专业
    for program_and_url in programs_and_url_list:
        program_name = program_and_url.get("program")
        program_url = program_and_url.get("url")
        # 获取url的md5值
        program_url_md5 = CommonUtils.EncryUtils.get_md5_by_url(program_url)
        # 匹配映射文件
        url_mapping = get_file_name_by_md5(program_url_md5)
        # 如果不存在该专业的页面信息
        if url_mapping is None:
            logging.warning("映射文件中不存在该页面的映射信息：" + program_url)
            continue
        # 存在该专业的页面信息
        # 拼接专业信息页面的全路径
        program_html_parent_path = os.path.join(source_path, "data")
        program_html_path = os.path.join(program_html_parent_path, program_url_md5 + ".html")
        # 验证页面是否存在
        if not os.path.exists(program_html_path):
            logging.warning("目录中不存在该页面" + program_html_path)
            continue
        print("要解析的专业信息页面路径:", program_html_path)
        program_tree = HTMLTREE(program_html_path, HtmlXPath.PROGRAM_XPATH)
        program_info = program_tree.parse_program_html()

        # 拼接存放信息的父路径
        program_target_parent_path = os.path.join(source_path, "target")
        if not os.path.exists(program_target_parent_path):
            os.mkdir(program_target_parent_path)

        # todo 存放解析信息的文件类型可以对外暴露
        program_target_path = os.path.join(program_target_parent_path, program_name + ".txt")
        with open(program_target_path, 'w', encoding='utf-8') as file:
            file.write(str(program_info))
